package com.beidu.lottery.call.service.portal.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.beidu.lottery.call.common.BaseContextHandler;
import com.beidu.lottery.call.constant.ActivityGroundingStatusEnum;
import com.beidu.lottery.call.constant.ActivityShareTypeEnum;
import com.beidu.lottery.call.constant.ActivityTypeEnum;
import com.beidu.lottery.call.dao.ActivityBaseInfoMapper;
import com.beidu.lottery.call.entity.ActivityBaseInfo;
import com.beidu.lottery.call.entity.ActivityRule;
import com.beidu.lottery.call.entity.form.InfoSaveStep1Form;
import com.beidu.lottery.call.entity.form.InfoSaveStep2Form;
import com.beidu.lottery.call.entity.query.ActivityListQuery;
import com.beidu.lottery.call.entity.vo.ActivityInfoListVO;
import com.beidu.lottery.call.entity.vo.ActivityInfoStep1VO;
import com.beidu.lottery.call.entity.vo.ActivityInfoStep2VO;
import com.beidu.lottery.call.exception.ServiceException;
import com.beidu.lottery.call.mq.event.ActivityDelayCloseEvent;
import com.beidu.lottery.call.mq.rocket.producer.ActivityDelayCloseProducer;
import com.beidu.lottery.call.service.portal.ActivityBaseInfoService;
import com.beidu.lottery.call.service.portal.ActivityRuleService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 活动基础信息表 服务实现类
 * </p>
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ActivityBaseInfoServiceImpl extends ServiceImpl<ActivityBaseInfoMapper, ActivityBaseInfo> implements ActivityBaseInfoService {

    private final ActivityBaseInfoMapper activityBaseInfoMapper;
    private final ActivityRuleService ruleService;
    private final ActivityDelayCloseProducer activityDelayCloseProducer;

    @Override
    public PageInfo<ActivityInfoListVO> queryActivityList(ActivityListQuery query) {
        query.setTenantCode(BaseContextHandler.getTenant());
        query.setUserId(BaseContextHandler.getUserId());
        PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<ActivityInfoListVO> infoListVOS = activityBaseInfoMapper.queryActivityList(query);
        infoListVOS.forEach(a -> {
            LocalDateTime now = LocalDateTime.now();
            if (now.isBefore(a.getActivityBeginTime())) {
                a.setActivityStatus(1);
            } else if (now.isBefore(a.getActivityEndTime())) {
                a.setActivityStatus(0);
            } else {
                a.setActivityStatus(2);
            }
        });
        return new PageInfo<>(infoListVOS);
    }

    @Override
    @Transactional
    public Integer saveBaseInfoStep1(InfoSaveStep1Form form) {
        if (ObjectUtil.isNull(form.getActivityBeginTime()) || ObjectUtil.isNull(form.getActivityEndTime())) {
            throw new ServiceException("活动开始、结束时间不能为空");
        }
        //校验 活动开始时间小于结束时间
        if (form.getActivityEndTime().isBefore(form.getActivityBeginTime())) {
            throw new ServiceException("活动结束时间不能早于活动开始时间");
        }
        ActivityBaseInfo baseInfo = new ActivityBaseInfo();
        BeanUtils.copyProperties(form, baseInfo);
        baseInfo.setGroundingStatus(ActivityGroundingStatusEnum.ACTIVITY_DRAFT.code);
        //通过id判断是否为新增
        baseInfo.setShare(ActivityShareTypeEnum.DO_NOT_SHARE.code);
        if (Objects.isNull(form.getId())) {
            baseInfo.setCreatedBy(BaseContextHandler.getUserId());
            baseInfo.setTenantCode(BaseContextHandler.getTenant());
            activityBaseInfoMapper.insert(baseInfo);
        } else {
            ActivityBaseInfo activityBaseInfo = activityBaseInfoMapper.selectById(baseInfo.getId());
            if (ActivityGroundingStatusEnum.ACTIVITY_GROUNDING.code.compareTo(activityBaseInfo.getGroundingStatus()) == 0) {
                throw new ServiceException("活动上架中，请下架后进行修改");
            }
            baseInfo.setUpdatedBy(BaseContextHandler.getUserId());
            activityBaseInfoMapper.updateById(baseInfo);
        }
        // 发送延时消息队列，等待活动到期后，将活动状态置为已过期
        ActivityDelayCloseEvent activityDelayCloseEvent = ActivityDelayCloseEvent.builder()
                .activityId(baseInfo.getId())
                .userId(BaseContextHandler.getUserId())
                .delayTime(DateUtil.parse(String.valueOf(form.getActivityEndTime())).getTime())
                .build();
        SendResult sendResult = activityDelayCloseProducer.sendMessage(activityDelayCloseEvent);
        // 发送消息失败解决方案简单且高效的逻辑之一：打印日志并报警，通过日志搜集并重新投递
        if (ObjectUtil.notEqual(sendResult.getSendStatus().name(), "SEND_OK")) {
            log.warn("发送活动状态关闭延时队列失败，消息参数：{}", JSON.toJSONString(activityDelayCloseEvent));
        }
        return baseInfo.getId();
    }

    @Override
    public ActivityInfoStep1VO queryInfoStep1(Integer id) {
        if (Objects.isNull(id)) {
            return null;
        }
        ActivityBaseInfo activityBaseInfo = activityBaseInfoMapper.selectById(id);
        if (Objects.isNull(activityBaseInfo)) {
            return null;
        }
        ActivityInfoStep1VO vo = new ActivityInfoStep1VO();
        BeanUtils.copyProperties(activityBaseInfo, vo);
        return vo;
    }

    @Override
    @Transactional
    public void saveBaseInfoStep2(InfoSaveStep2Form form) {
        //判断活动类型
        ActivityBaseInfo baseInfo = activityBaseInfoMapper.selectById(form.getActivityId());
        if (Objects.isNull(baseInfo))
            throw new ServiceException("活动不存在");
        if (ActivityTypeEnum.REG.getCode().equals(baseInfo.getActivityType())) {
            //判断报名人数
            if (Objects.isNull(form.getNumberLimit())) {
                throw new ServiceException("活动人数不能为空");
            }
        } else if (ActivityTypeEnum.VOTE.getCode().equals(baseInfo.getActivityType())) {
            //投票次数默认为0
            if (ObjectUtil.isNull(form.getAccountVoteLimit())) {
                form.setAccountVoteLimit(0);
            }
        } else {
            //抽奖活动助力人数如果为null，设置为0
            if (ObjectUtil.isNull(form.getLotteryExtraNumber())) {
                form.setLotteryExtraNumber(0);
            }
        }
        //消耗积分如果为空，则默认为0
        if (ObjectUtil.isNull(form.getConsumePoints()))
            form.setConsumePoints(0);
        //查询当前活动是否已存在活动规则，如果存在则更新
        ActivityRule one = ruleService.getOne(new LambdaQueryWrapper<ActivityRule>().eq(ActivityRule::getActivityId, form.getActivityId()));
        if (Objects.isNull(one)) {
            ActivityRule build = ActivityRule.builder().build();
            BeanUtils.copyProperties(form, build);
            build.setCreatedBy(BaseContextHandler.getUserId());
            build.setCreatedDate(LocalDateTime.now());
            ruleService.save(build);
        } else {
            if (ActivityGroundingStatusEnum.ACTIVITY_GROUNDING.code.compareTo(baseInfo.getGroundingStatus()) == 0) {
                throw new ServiceException("活动上架中，请下架后进行修改");
            }
            BeanUtils.copyProperties(form, one);
            one.setUpdatedBy(BaseContextHandler.getUserId());
            ruleService.updateById(one);
        }
    }

    @Override
    public ActivityInfoStep2VO queryInfoStep2(Integer id) {
        return ruleService.queryActivityRules(id);
    }

}
